package com.ideal.frame.jpa;

import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.BooleanExpression;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.querydsl.QSort;

import java.util.List;

public class DSLPageRequest extends DSLRequest implements Pageable {
    private final Integer page;
    private final Integer size;

    public DSLPageRequest(Integer page, Integer size) {
        this.page = page == null ? 0 : page.intValue();
        this.size = size == null ? 0 : size.intValue();
    }

    public DSLPageRequest(Integer page, Integer size, List<BooleanExpression> where, List<OrderSpecifier<? extends Comparable>> orderByList) {
        super(where, orderByList);
        this.page = page == null ? 0 : page.intValue();
        this.size = size == null ? 0 : size.intValue();
    }

    public DSLPageRequest(Integer page, Integer size, List<BooleanExpression> where) {
        super(where);
        this.page = page == null ? 0 : page.intValue();
        this.size = size == null ? 0 : size.intValue();
    }

    @Override
    public int getPageNumber() {
        return this.page.intValue();
    }

    @Override
    public int getPageSize() {
        return this.size.intValue();
    }

    @Override
    public long getOffset() {
        return this.page.intValue() * this.size.intValue();
    }

    @Override
    public Sort getSort() {
        return this.orderByList != null && this.orderByList.size() > 0 ? new QSort(this.orderByList) : null;
    }

    @Override
    public boolean hasPrevious() {
        return this.page.intValue() > 0;
    }

    @Override
    public DSLPageRequest previousOrFirst() {
        return this.hasPrevious() ? this.previous() : this.first();
    }

    @Override
    public DSLPageRequest next() {
        return new DSLPageRequest(this.getPageNumber() + 1, this.getPageSize(), this.where, this.orderByList);
    }

    public DSLPageRequest previous() {
        return this.getPageNumber() == 0 ? this : new DSLPageRequest(this.getPageNumber() - 1, this.getPageSize(), this.where, this.orderByList);
    }

    @Override
    public DSLPageRequest first() {
        return new DSLPageRequest(Integer.valueOf(0), this.getPageSize(), this.where, this.orderByList);
    }

    public Pageable asPageable() {
        return PageRequest.of(this.page.intValue(), this.size.intValue());
    }
}
